package com.zhouyu.mybatis.spring;

import com.zhouyu.mapper.OrderMapper;
import com.zhouyu.mapper.UserMapper;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

import java.io.IOException;
import java.util.Map;

/**
 * @author 周瑜
 */
public class ZhouyuImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
		// 扫描路径
		Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(ZhoyuMapperScan.class.getName());
		String path = (String) annotationAttributes.get("value");

		//mybatis 在ImportBeanDefinitionRegistrar 中只是把MapperScannerConfigurer（一个BeanDefinitionRegistryPostProcessor）
		// 注册成了一个bd，扫描操作是在之后的BeanDefinitionRegistryPostProcessor中完成的
		//自己定义的ClassPathBeanDefinitionScanner 与Spring容器自身构造方法中的扫描器不同
		//我们要扫描自己定义的注解成为bean时，可以自己定义一个ClassPathBeanDefinitionScanner
		// 然后在ImportBeanDefinitionRegistrar中进行扫描
		ZhouyuBeanDefinitionScanner scanner = new ZhouyuBeanDefinitionScanner(registry);

		scanner.addIncludeFilter(new TypeFilter() {
			@Override
			public boolean match(@NotNull MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
				//这里的匹配器决定扫描到的类是否加入到BeanDefinitionMap中
				return true;
			}
		});

		scanner.scan(path);
	}
}
